//
//  File.swift
//
//
//  Created by didi on 2022/9/13.
//

import Fluent
import MolecularObjects
import Vapor

extension Variable.List: Content { }
extension Variable.Detail: Content { }

struct SystemVariableApiController: ApiController {
    typealias ApiModel = Variable
    typealias DatabaseModel = SystemVariableModel

    typealias CreateContext = Variable.Create
    
    func listOutput(_ req: Request, _ models: [SystemVariableModel]) async throws -> [Variable.List] {
        models.map {
            .init(id: $0.uuid, key: $0.key, value: $0.value)
        }
    }

    func detailOutput(_ req: Request, _ model: SystemVariableModel) async throws -> Variable.Detail {
        .init(id: model.uuid, key: model.key, name: model.name, value: model.value, notes: model.notes)
    }

    func createInput(_ req: Request, _ model: SystemVariableModel, _ input: Variable.Create) async throws {
        model.key = input.key
        model.name = input.name
        model.value = input.value
        model.notes = input.notes
    }

    func updateInput(_ req: Request, _ model: DatabaseModel, _ input: Variable.Update) async throws {
        model.key = input.key
        model.name = input.name
        model.value = input.value ?? model.value
        model.notes = input.notes ?? model.notes
    }

    func patchInput(_ req: Request, _ model: DatabaseModel, _ input: Variable.Patch) async throws {
        model.key = input.key ?? model.key
        model.name = input.name ?? model.name
        model.value = input.value ?? model.value
        model.notes = input.notes ?? model.notes
    }

    @AsyncValidatorBuilder
    func validators(optional: Bool) -> [AsyncValidator] {
        KeyedContentValidator<String>.required("key")
        KeyedContentValidator<String>.required("name")
        KeyedContentValidator<String>("key", "Key must be unique", optional: optional) { req, value in
            try await req.system.variable.repository.isUnique(\.$key == value, Variable.getIdParameter(req))
        }
    }
}
